using System.Collections.Generic;
using EnvDTE80;
using NUnit.Framework;
using Rhino.Mocks;
using TddGenerator.Core.Domain;
using TddGenerator.Core.Services;
using TddGenerator.Core.Services.Impl;

namespace TddGenerator.UnitTests.Services
{
    [TestFixture]
    public class ClassGeneratorTester
    {
        [Test]
        public void ClassGenerator_should()
        {
            var mocks = new MockRepository();
            var templateSetRepository = mocks.CreateMock<ITemplateSetRepository>();
            var dte = mocks.DynamicMock<DTE2>();
            var ideService = mocks.CreateMock<IVsIdeService>();
            var projectRepository = mocks.CreateMock<IProjectRepository>();
            var tokenGenerator = mocks.CreateMock<ITokenFactory>();
            var configurationRepository = mocks.CreateMock<IConfigurationRepository>();

            var templateSet = new TemplateSet();
            templateSet.ClassTemplate = "classtempate";
            templateSet.FileExtension = ".cs";
            templateSet.InterfaceTemplate = "interfaceTemplateName";
            templateSet.Language = "CSharp";
            templateSet.TestClass = "testclasstemplatename";


            var classToCreate = new ClassToCreate();
            classToCreate.ClassName = "classname";
            classToCreate.ClassProject = "classproject";
            classToCreate.FolderHierarchy = new List<string>() {"folder", "folder2"};
            classToCreate.TestProject = "TestProject";

            var implementationFolder = new List<string>( classToCreate.FolderHierarchy) {"Impl"};

            var configuration = new GeneratorConfiguration();

            Dictionary<string, string> tokens = new Dictionary<string, string>();

            using (mocks.Record())
            {
                using (mocks.Unordered())
                {
                    Expect.Call(configurationRepository.Get()).Return(configuration);

                    Expect.Call(templateSetRepository.Get()).Return(templateSet);
                }
                
                ideService.CreateFolderHierarchy(classToCreate.ClassProject,null);
                LastCall.IgnoreArguments().Repeat.Times(3);

                using (mocks.Unordered())
                {
                    ideService.AddFileToFolder(classToCreate.ClassProject, implementationFolder,
                                               classToCreate.ClassName + templateSet.FileExtension, templateSet.ClassTemplate);

                    
                    ideService.AddFileToFolder(classToCreate.ClassProject, classToCreate.FolderHierarchy,
                                               configuration.InterfacePrefix + classToCreate.ClassName +
                                               templateSet.FileExtension, templateSet.InterfaceTemplate);

                    ideService.AddFileToFolder(classToCreate.TestProject, classToCreate.FolderHierarchy,
                                               classToCreate.ClassName + configuration.TestSufix +
                                               templateSet.FileExtension, templateSet.TestClass);
                }


                Expect.Call(tokenGenerator.Create(classToCreate, templateSet, configuration, implementationFolder)).Return(tokens);

                using (mocks.Unordered())
                {
                    ideService.ReplaceTokens(classToCreate.ClassProject, implementationFolder,
                                             classToCreate.ClassName + templateSet.FileExtension, tokens);

                    ideService.ReplaceTokens(classToCreate.ClassProject, classToCreate.FolderHierarchy,
                                             configuration.InterfacePrefix + classToCreate.ClassName +
                                             templateSet.FileExtension, tokens);

                    ideService.ReplaceTokens(classToCreate.TestProject, classToCreate.FolderHierarchy,
                                             classToCreate.ClassName + configuration.TestSufix +
                                             templateSet.FileExtension, tokens);
                }
            }

            using (mocks.Playback())
            {
                IClassGenerator generator = new ClassGenerator(templateSetRepository, ideService, projectRepository,tokenGenerator,configurationRepository);
                generator.CreateClasses(classToCreate);
            }

            mocks.VerifyAll();
        }
    }
}